﻿using System;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Workflow;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Publishing.Navigation;
using Microsoft.SharePoint.Taxonomy;
using System.Collections;
using System.Linq;
using System.Collections.Generic;
using System.IO;
using System.Xml;

namespace ManagedMetadataNavigation.PageItemReceiver
{
    /// <summary>
    /// List Item Events
    /// </summary>
    public class PageItemReceiver : SPItemEventReceiver
    {
        /// <summary>
        /// An item is being deleted.
        /// </summary>
        public override void ItemDeleting(SPItemEventProperties properties)
        {
            try
            {
                string fileurl = properties.ListItem.File.Url;
                if (fileurl != properties.ListItem.Web.RootFolder.WelcomePage && !fileurl.Contains("_catalogs"))
                {   
                    SPWeb web = properties.List.ParentWeb;
                    SPListItem item = properties.ListItem;
                    SPWeb current_parentweb = web.ParentWeb;
                    SPWeb current_rootweb = web.Site.RootWeb;
                    AddDeleteNavigation(web, current_parentweb, current_rootweb, true, item);
                }
            }
            catch (Exception ex)
            {
                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Managed Metadata", TraceSeverity.Unexpected, EventSeverity.Information), TraceSeverity.Unexpected, "Page item Deleting " + ex.Message);
            }
        }

        /// <summary>
        /// An item is being checked in.
        /// </summary>
        public override void ItemCheckingIn(SPItemEventProperties properties)
        {
            try
            {
                string fileurl = properties.ListItem.File.Url;
                if (fileurl != properties.ListItem.Web.RootFolder.WelcomePage && !fileurl.Contains("_catalogs"))
                {                   
                   
                    SPWeb web = properties.List.ParentWeb;
                    string listurl = properties.ListItem[SPBuiltInFieldId.EncodedAbsUrl].ToString();
                    SPListItem item = web.GetListItem(listurl);
                    SPWeb current_parentweb = web.ParentWeb;
                    SPWeb current_rootweb = web.Site.RootWeb;
                    
                    AddDeleteNavigation(web, current_parentweb, current_rootweb, false, item);                   




                }

            }
            catch (Exception ex)
            {
                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Managed Metadata", TraceSeverity.Unexpected, EventSeverity.Information), TraceSeverity.Unexpected, "page item adding " + ex.Message);
            }
        }


        private void AddDeleteNavigation(SPWeb currentweb, SPWeb parentweb, SPWeb current_rootweb, Boolean Delete, SPListItem item)
        {
            try
            {
                
                IList urlpartslists = currentweb.ServerRelativeUrl.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
                ///variable declaration            
                
                string pagetitle = item.DisplayName;
                string currentweb_url = urlpartslists[urlpartslists.Count - 1].ToString();                
                string currenweb_relativeurl = currentweb.ServerRelativeUrl.ToString().Replace(current_rootweb.ServerRelativeUrl.ToString(), "");
                SPWebApplication webApp = currentweb.Site.WebApplication;
                String filenameconnection = webApp.IisSettings[SPUrlZone.Default].Path.ToString() + "\\" + "web.config";
                Dictionary<String, String> keys = getappkeys(filenameconnection);
                ///taxonomy declartion
                ///

                TaxonomySession taxSession = new TaxonomySession(currentweb.Site);
                TermStore TermStore = taxSession.TermStores[0];

                Group termgroup = TermStore.Groups[keys["Site Navigation"]];
                
                TermSet currenterm = termgroup.TermSets[urlpartslists[0].ToString()];
                NavigationTermSet navTermSet = NavigationTermSet.GetAsResolvedByWeb(currenterm, current_rootweb, StandardNavigationProviderNames.GlobalNavigationTaxonomyProvider);
                


                if (currentweb.IsRootWeb)
                {
                    NavigationTerm curr_web_term_exists = navTermSet.Terms.Where(t => t.Title.ToString() == pagetitle).FirstOrDefault();
                    if (Delete && curr_web_term_exists != null)
                    {
                        curr_web_term_exists.Delete();
                       
                    }
                    else
                        if (!Delete && curr_web_term_exists == null)
                        {
                            
                            curr_web_term_exists = navTermSet.CreateTerm(pagetitle, NavigationLinkType.FriendlyUrl);
                            curr_web_term_exists.FriendlyUrlSegment.Value = pagetitle;
                            curr_web_term_exists.TargetUrl.Value = "~sitecollection" + "/" + item.File.Url.ToString();

                        }
                    TermStore.CommitAll();

                }
                #region parentwebchild
                else if ((!currentweb.IsRootWeb) && (currentweb.ParentWeb.IsRootWeb))
                {

                    try
                    {
                        NavigationTerm curr_web_term_exists = navTermSet.Terms.Where(t => t.Title.ToString() == urlpartslists[1].ToString().Replace("_", "")).FirstOrDefault();
                        NavigationTerm curr_page_term_exists = curr_web_term_exists.Terms.Where(t => t.Title.ToString() == pagetitle).FirstOrDefault();
                        if (Delete && curr_page_term_exists != null)
                        {
                           
                            curr_page_term_exists.Delete();

                        }
                        else if (curr_page_term_exists == null && !Delete)
                        {
                           
                            curr_page_term_exists = curr_web_term_exists.CreateTerm(pagetitle, NavigationLinkType.FriendlyUrl);
                            curr_page_term_exists.FriendlyUrlSegment.Value = pagetitle;
                            curr_page_term_exists.TargetUrl.Value = "~sitecollection" + "/" + currenweb_relativeurl + "/" + item.File.Url.ToString();


                        }


                        TermStore.CommitAll();

                    }
                    catch (Exception ex)
                    {
                        SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Managed Metadata", TraceSeverity.Unexpected, EventSeverity.Information), TraceSeverity.Unexpected, "page item receiver " + ex.Message);

                    }

                }
                #endregion

                #region notchildofrootweb
                else
                    if (!currentweb.ParentWeb.IsRootWeb && !currentweb.IsRootWeb)
                    {
                        try
                        {

                            NavigationTerm first_term = navTermSet.Terms.Where(t => t.Title.ToString() == urlpartslists[1].ToString().Replace("_", "")).FirstOrDefault();
                            NavigationTerm parent_term = null;

                            if ((first_term.Title.ToString() == urlpartslists[2].ToString().Replace("_", "")) && urlpartslists.Count == 3)
                            {
                                NavigationTerm pageterm = first_term.Terms.Where(t => t.Title.ToString() == pagetitle).FirstOrDefault();
                                if (Delete != true && pageterm == null)
                                {
                                    
                                    NavigationTerm newterm = first_term.CreateTerm(pagetitle, NavigationLinkType.FriendlyUrl);
                                    newterm.FriendlyUrlSegment.Value = pagetitle;
                                    newterm.TargetUrl.Value = "~sitecollection" + "/" + currenweb_relativeurl + "/" + item.File.Url;
                                }
                                else
                                    if (Delete)
                                    {
                                        
                                        NavigationTerm delteterm = first_term.Terms.Where(t => t.Title.ToString() == pagetitle).FirstOrDefault();
                                        delteterm.Delete();

                                    }

                            }
                            else
                            {
                                for (int i = urlpartslists.Count - 1; i > 0; i--)
                                {
                                    parent_term = first_term.Terms.Where(t => t.Title.ToString() == (urlpartslists[i].ToString().Replace("_", ""))).FirstOrDefault();
                                    if (parent_term != null && i == urlpartslists.Count - 1)
                                    {
                                        NavigationTerm curr_page_term_exists = parent_term.Terms.Where(t => t.Title.ToString() == pagetitle).FirstOrDefault();
                                        if (Delete && curr_page_term_exists != null)
                                        {
                                           

                                            curr_page_term_exists.Delete();



                                        }
                                        else
                                            if (!Delete && curr_page_term_exists == null)
                                            {
                                               
                                                NavigationTerm newterm = parent_term.CreateTerm(pagetitle, NavigationLinkType.FriendlyUrl);
                                                newterm.FriendlyUrlSegment.Value = pagetitle;
                                                newterm.TargetUrl.Value = "~sitecollection" + "/" + currenweb_relativeurl + "/" + item.File.Url;
                                            }
                                        break;
                                    }
                                    else if (parent_term != null)
                                    {
                                        first_term = parent_term;
                                        parent_term = null;
                                        i = urlpartslists.Count;

                                    }
                                }
                            }
                            TermStore.CommitAll();

                        }
                        catch (Exception ex)
                        {
                            SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Managed Metadata", TraceSeverity.Unexpected, EventSeverity.Information), TraceSeverity.Unexpected, "page item receiver " + ex.Message);

                        }


                    }
                #endregion
            }
            catch (Exception ex)
            {
                SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("Managed Metadata", TraceSeverity.Unexpected, EventSeverity.Information), TraceSeverity.Unexpected, "page item receiver " + ex.Message);
            }
        }

        private Dictionary<String, String> getappkeys(string path)
        {
            Dictionary<String, String> appkeys = new Dictionary<string, string>();
            if (File.Exists(path))
            {
                StreamReader reader = new StreamReader
                (
                    new FileStream(
                        path,
                        FileMode.Open,
                        FileAccess.Read,
                        FileShare.Read)
                );
                XmlDocument doc = new XmlDocument();
                string xmlIn = reader.ReadToEnd();
                reader.Close();
                doc.LoadXml(xmlIn);
                XmlElement configelement = doc.DocumentElement;
                XmlNode appsettingsnode = configelement.SelectSingleNode("/configuration/appSettings");


                XmlNodeList currentchilds = appsettingsnode.ChildNodes;
                if (currentchilds.Count > 0)
                {

                    for (int i = 0; i < currentchilds.Count; i++)
                    {
                        var child = currentchilds[i];
                        XmlAttributeCollection att = child.Attributes;
                        if (att != null && att.Count > 1)
                        {
                            if (att[0] != null && att[1] != null)
                            {
                                if (!appkeys.ContainsKey(Convert.ToString(att[0].Value)))
                                {
                                    appkeys.Add(att[0].Value, att[1].Value);
                                }
                            }
                        }
                    }
                }

            }

            return (appkeys);

        }

    }
}